#ifndef CLCOMCONFIGFILE_H
#define CLCOMCONFIGFILE_H

#include <QtCore/qglobal.h>

#include "CLComLibrarys_global.h"
//CLCOMLIBRARYS_EXPORT

#include <string>
#include <map>
#include <vector>
#include <string.h>

using namespace std;

enum CLCOM_CONFIGFILE_RETURNVALUE
{
    CLCOM_CONFIGFILE_RETURNVALUE_NONODES	= -5,
    CLCOM_CONFIGFILE_RETURNVALUE_OB_NOCALLBACK = -4,
    CLCOM_CONFIGFILE_RETURNVALUE_NODE_NOTEXIST = -3,

    CLCOM_CONFIGFILE_RETURNVALUE_FILENOTEXIST = -2,
    CLCOM_CONFIGFILE_RETURNVALUE_FILEHADOPEN = -1,
    CLCOM_CONFIGFILE_RETURNVALUE_FALSE = 0,
    CLCOM_CONFIGFILE_RETURNVALUE_OK,
    CLCOM_CONFIGFILE_RETURNVALUE_FILECRAETE,
    CLCOM_CONFIGFILE_RETURNVALUE_FILECHANGED,
    CLCOM_CONFIGFILE_RETURNVALUE_FILENOTCHANGED,

};
enum CLCOM_CONFIGFILE_DATATYPE
{
    CLCOM_CONFIGFILE_DATATYPE_NO = 0,
    CLCOM_CONFIGFILE_DATATYPE_INT,
    CLCOM_CONFIGFILE_DATATYPE_DOUBLE,
    CLCOM_CONFIGFILE_DATATYPE_CHARS,
};

#define F_XML_VALUE_LEN 256
#define F_XML_NAME_LEN 64
#define F_XML_ATTR_LEN 256
#define F_XML_ID_LEN 32

#define F_INVALID_VALUE -222

typedef struct CLCOMLIBRARYS_EXPORT _tagConfigNodeInfo
{
    CLCOM_CONFIGFILE_DATATYPE useType;
    int nValue;
    double dValue;
    char czValue[F_XML_VALUE_LEN];

    char czName[F_XML_NAME_LEN];
    char czAttribute[F_XML_ATTR_LEN];

    char czID[F_XML_ID_LEN];

    _tagConfigNodeInfo()
    {
        memset((void*)this, 0, sizeof(_tagConfigNodeInfo));
    }
    _tagConfigNodeInfo(const _tagConfigNodeInfo& other)
    {
        memcpy((void*)this, (void*)&other, sizeof(_tagConfigNodeInfo));
    }
    _tagConfigNodeInfo& operator=(const _tagConfigNodeInfo& other)
    {
        memcpy((void*)this, (void*)&other, sizeof(_tagConfigNodeInfo));
        return *this;
    }

}CONFIGNODEINFO, *PCONFIGNODEINFO;

typedef void(*PVALUECHANGECALLBACK)(const char* fullNodeName, CONFIGNODEINFO node);

typedef struct CLCOMLIBRARYS_EXPORT _tagCLComConfigFileInitInfo
{
    bool					_bCreateFile;
    PVALUECHANGECALLBACK	_pChangeCallBack;
    char					_czFilename[256];

    _tagCLComConfigFileInitInfo()
    {
        memset((void*)this, 0, sizeof(_tagCLComConfigFileInitInfo));
    }
    _tagCLComConfigFileInitInfo(const _tagCLComConfigFileInitInfo& other)
    {
        memcpy((void*)this, (void*)&other, sizeof(_tagCLComConfigFileInitInfo));
    }
    _tagCLComConfigFileInitInfo& operator=(const _tagCLComConfigFileInitInfo& other)
    {
        memcpy((void*)this, (void*)&other, sizeof(_tagCLComConfigFileInitInfo));
        return *this;
    }
}CLCOMCONFIGFILEINFO, *PCLCOMCONFIGFILEINFO;

// 此类是从 CLComConfigFile.dll 导出的
class CLCOMLIBRARYS_EXPORT CLComConfigFile
{
public:
    static CLCOM_CONFIGFILE_RETURNVALUE CreateConfigOJB(CLComConfigFile** ppObj, CLCOMCONFIGFILEINFO initInfo);
    static CLComConfigFile* GetConfigOJB(const char* filename);
    static void ReleaseConfigOBJ(CLComConfigFile** ppObj);
public:
    //文件是否可用
    virtual CLCOM_CONFIGFILE_RETURNVALUE IsFileValid() = 0;

    //打印该配置文件的自我描述信息
    virtual string DescriptionMyself() = 0;

    //备份该配置文件
    virtual CLCOM_CONFIGFILE_RETURNVALUE Backup() = 0;

    //还原该配置文件
    virtual CLCOM_CONFIGFILE_RETURNVALUE Restore() = 0;

    //重新加载文件
    virtual CLCOM_CONFIGFILE_RETURNVALUE Reload() = 0;

public:

    //添加节点监控，如果值发生改变则触发回调，父节点传入可以区别其他的长类节点：fathernode||node
    virtual CLCOM_CONFIGFILE_RETURNVALUE AddNode2Observer(CLCOM_CONFIGFILE_DATATYPE usetype, const char* nodename, const char* distFahterName = "") = 0;

    //从监控中移除节点
    virtual CLCOM_CONFIGFILE_RETURNVALUE RemoveNodeFromObserver(const char* nodename, const char* distFahterName = "") = 0;

public:

    //更新节点，包括修改值或者添加节点
    virtual CLCOM_CONFIGFILE_RETURNVALUE UpdateNode(CONFIGNODEINFO initInfo, const char* nodename, const char* distFahterName = "") = 0;

    //删除节点
    virtual CLCOM_CONFIGFILE_RETURNVALUE DelNode(const char* nodename, const char* distFahterName = "") = 0;


    //节点是否存在
    virtual bool IsNodeExist(const char* nodename, const char* distFahterName = "") = 0;

public:
    //获取节点信息
    virtual CLCOM_CONFIGFILE_RETURNVALUE GetNodeInfoByID(const char* nodeID, CONFIGNODEINFO& nodeInfo) = 0;

public:

    //获取节点的INT值,如果不存在则返回默认值
    virtual int GetINTValue(int defaultValue, const char* nodename, const char* distFahterName = "") = 0;

    //获取节点的double值,如果不存在则返回dDefaultValue
    virtual double GetDOUBLEValue(double dDefaultValue, const char* nodename, const char* distFahterName = "") = 0;

    //获取节点的chars值,如果不存在则返回strDefaultValue
    virtual std::string GetStringValue(string strDefaultValue, const char* nodename, const char* distFahterName = "") = 0;

public:
    //查找所有一级子节点,节点名称相似匹配
    virtual CLCOM_CONFIGFILE_RETURNVALUE FindAllSonNodesFirstLevel(vector<CONFIGNODEINFO>& outVecNodes, const char* nodename, const char* distFahterName = "", const char* nodeLikeThis = "") = 0;

    //查找所有兄弟节点 节点名称相似匹配
    virtual CLCOM_CONFIGFILE_RETURNVALUE FindAllBrotherNodesFirstLevel(vector<CONFIGNODEINFO>& outVecNodes, const char* nodename, const char* distFahterName = "", const char* nodeLikeThis = "") = 0;


public:

    //获取节点的INT值,如果不存在则返回默认值
    virtual int GetINTValueEx(int defaultValue, const char* nodeID) = 0;

    //获取节点的double值,如果不存在则返回dDefaultValue
    virtual double GetDOUBLEValueEx(double dDefaultValue, const char* nodeID) = 0;

    //获取节点的chars值,如果不存在则返回strDefaultValue
    virtual std::string GetStringValueEx(string strDefaultValue, const char* nodeID) = 0;

public:
    //查找所有一级子节点,节点名称相似匹配
    virtual CLCOM_CONFIGFILE_RETURNVALUE FindAllSonNodesFirstLevelEx(vector<CONFIGNODEINFO>& outVecNodes, const char* nodeID, const char* nodeLikeThis = "") = 0;

    //查找所有兄弟节点 节点名称相似匹配
    virtual CLCOM_CONFIGFILE_RETURNVALUE FindAllBrotherNodesFirstLevelEx(vector<CONFIGNODEINFO>& outVecNodes, const char* nodeID, const char* nodeLikeThis = "") = 0;

    virtual std::string GetNodeID(string strNodeName, string fatherID="") = 0;
public:
    //给节点加属性
    virtual CLCOM_CONFIGFILE_RETURNVALUE UpdateExplain(const char* attributestr, const char* nodename, const char* distFahterName = "") = 0;
};

#endif // CLCOMCONFIGFILE_H
